#include "ShapeEmbryoEvaluator.h"

#include "../../../qt/Logger.h"

#include "EmbryoIndividual.h"
#include "EmbryoIndividualDevelopment.h"

#include "../../../physics/cpm/Cell.h"
#include "../../../physics/cpm/Physics.h"
#include "../../../physics/cpm/World.h"
//#include "../../../physics/cpm/shapes/ShapeIdentifier.h"
//#include "../../../physics/cpm/shapes/ShapeIdentifierGenerator3X3.h"

namespace GA {

/*
	ShapeEmbryoEvaluator
*/

ShapeEmbryoEvaluator::ShapeEmbryoEvaluator(int gridWidth, int gridHeight) :
	_gridWidth(gridWidth),
	_gridHeight(gridHeight),
	_shapeGrid(gridWidth, gridHeight) {}

double ShapeEmbryoEvaluator::evaluate(EmbryoIndividual const& individual) {
//	Logger::debug(">>> ShapeEmbryoEvaluator::evaluate()");

	EmbryoIndividualDevelopment development(_gridWidth, _gridHeight, individual, getDevelopmentLength());

//	/* world */
//	World world(_gridWidth, _gridHeight);

//	/* physics */
//	Physics physics(world);

//	/* shape identifier */
//	ShapeIdentifierGenerator3X3& generator = ShapeIdentifierGenerator3X3::getInstance();
//	ShapeIdentifier* shapeIdentifier       = generator.getNewShapeIdentifier();

	/* cell */
//	int cellSide = 1;
//	int cellSide = 3;
//	int cellSide = 6;
//	Cell* cell = new Cell(world, *shapeIdentifier, individual.getGenome(), cellSide * cellSide);

//	/* worldly cell */
//	world.addCell(cell);
//	int cellId = cell->getId();
//	int xCellOrigin = _gridWidth  / 2 - cellSide / 2;
//	int yCellOrigin = _gridHeight / 2 - cellSide / 2;
//	for(int i = 0; i != cellSide; ++i) {
//		for(int j = 0; j != cellSide; ++j) {
//			world.setTile(xCellOrigin + i, yCellOrigin + j, cellId);
//		}
//	}
//
//	/* run */
//	physics.run(getDevelopmentLength());

	World const& world = development.getWorld();

	/* compare */
	int difference = 0;
	for(int i = 0; i != _gridWidth; ++i) {
		for(int j = 0; j != _gridHeight; ++j) {
//			Logger::debug(QString("\tShapeEmbryoEvaluator::evaluate() comparing (%1, %2) : %3").arg(i).arg(j).arg(world.grid(i, j)));
			if (_shapeGrid.getTile(i, j) == 0) {
				if (world.grid(i, j) != 0) {
					++difference;
				}
			} else {
				if (world.grid(i, j) == 0) {
					++difference;
				}
			}
		}
	}

//	delete shapeIdentifier;

//	Logger::debug(QString("<<< ShapeEmbryoEvaluator::evaluate() : %1").arg(-difference));
	return - (double)difference;
}

/*	protected	*/

void ShapeEmbryoEvaluator::setShapePixel(int x, int y) {
	_shapeGrid.setTile(x, y, 1);
}

} // GA

